namespace Test
import Grawlix

struct A:
	
	val as int
	
	[Equality(InvertOperators: true)]
	private def Equality(rhs as Compare):
		return val == rhs.val

final class Compare:
	public val as int

a = A()
b as object = a
c = Compare()
d as object = c
#x as A = null # Can't convert null to A
y as Compare = null
z as object = null

assert not a.Equals(a) # No comparison defined
assert not a.Equals(b) # No comparison defined
assert     a.Equals(c)
assert     a.Equals(d)
#assert not a.Equals(x) # no x
assert not a.Equals(y)
assert not a.Equals(z)
assert not a.Equals(null)
assert not a == a # No comparison defined
assert not a == b # No comparison defined
assert     a == c
assert     a == d
#assert not a == x # no x
assert not a == y
assert not a == z
#assert not a == null # Can't convert null to A
assert     a != a # No comparison defined
assert     a != b # No comparison defined
assert not a != c
assert not a != d
#assert     a != x # no x
assert     a != y
assert     a != z
#assert     a != null # Can't convert null to A

assert not b.Equals(a) # No comparison defined
assert not b.Equals(b) # No comparison defined
assert     b.Equals(c)
assert     b.Equals(d)
#assert not b.Equals(x) # no x
assert not b.Equals(y)
assert not b.Equals(z)
assert not b.Equals(null)
assert not b == a # No comparison defined
assert     b == b
assert     b == c
assert     b == d
#assert not b == x # no x
assert not b == y
assert not b == z
assert not b == null
assert     b != a # No comparison defined
assert not b != b
assert not b != c
assert not b != d
#assert     b != x # no x
assert     b != y
assert     b != z
assert     b != null

assert not c.Equals(a) # Can't change original
assert not c.Equals(b) # Can't change original
assert     c.Equals(c)
assert     c.Equals(d)
#assert not c.Equals(x) # no x
assert not c.Equals(y)
assert not c.Equals(z)
assert not c.Equals(null)
assert     c == a
assert     c == b
assert     c == c
assert     c == d
#assert not c == x # no x
assert not c == y
assert not c == z
assert not c == null
assert not c != a
assert not c != b
assert not c != c
assert not c != d
#assert     c != x # no x
assert     c != y
assert     c != z
assert     c != null

assert not d.Equals(a) # Can't change original
assert not d.Equals(b) # Can't change original
assert     d.Equals(c)
assert     d.Equals(d)
#assert not d.Equals(x) # no x
assert not d.Equals(y)
assert not d.Equals(z)
assert not d.Equals(null)
assert     d == a
assert     d == b
assert     d == c
assert     d == d
#assert not d == x # no x
assert not d == y
assert not d == z
assert not d == null
assert not d != a
assert not d != b
assert not d != c
assert not d != d
#assert     d != x # no x
assert     d != y
assert     d != z
assert     d != null

# No x
#assert not x.Equals(a)
#assert not x.Equals(b)
#assert not x.Equals(c)
#assert not x.Equals(d)
#assert     x.Equals(x)
#assert     x.Equals(y)
#assert     x.Equals(z)
#assert     x.Equals(null)
#assert not x == a
#assert not x == b
#assert not x == c
#assert not x == d
#assert     x == x
#assert     x == y
#assert     x == z
#assert     x == null
#assert     x != a
#assert     x != b
#assert     x != c
#assert     x != d
#assert not x != x
#assert not x != y
#assert not x != z
#assert not x != null

# Cannot call method on null
#assert not y.Equals(a)
#assert not y.Equals(b)
#assert not y.Equals(c)
#assert not y.Equals(d)
#assert     y.Equals(x)
#assert     y.Equals(y)
#assert     y.Equals(z)
#assert     y.Equals(null)
assert not y == a
assert not y == b
assert not y == c
assert not y == d
#assert     y == x # no x
assert     y == y
assert     y == z
assert     y == null
assert     y != a
assert     y != b
assert     y != c
assert     y != d
#assert not y != x # no x
assert not y != y
assert not y != z
assert not y != null

# Cannot call method on null
#assert not z.Equals(a)
#assert not z.Equals(b)
#assert not z.Equals(c)
#assert not z.Equals(d)
#assert     z.Equals(x)
#assert     z.Equals(y)
#assert     z.Equals(z)
#assert     z.Equals(null)
assert not z == a
assert not z == b
assert not z == c
assert not z == d
#assert     z == x # no x
assert     z == y
assert     z == z
assert     z == null
assert     z != a
assert     z != b
assert     z != c
assert     z != d
#assert not z != x # no x
assert not z != y
assert not z != z
assert not z != null

# Cannot call method on null
#assert not null.Equals(a)
#assert not null.Equals(b)
#assert not null.Equals(c)
#assert not null.Equals(d)
#assert     null.Equals(x)
#assert     null.Equals(y)
#assert     null.Equals(z)
#assert     null.Equals(null)
#assert not null == a # Can't convert null to A
assert not null == b
assert not null == c
assert not null == d
#assert     null == x # no x
assert     null == y
assert     null == z
assert     null == null
#assert     null != a # Can't convert null to A
assert     null != b
assert     null != c
assert     null != d
#assert not null != x # no x
assert not null != y
assert not null != z
assert not null != null

